MYC-deficiency impairs the development of effector/memory T lymphocytes

Authors :Mathis Nozais1*, Marie Loosveld1,2*, Saran Pankaew1, Clémence Grosjean1, Noémie Gentil1, Julie Quessada1, Cyrille Mionnet1, Delphine Potier1@ & Dominique Payet-Bornet1@

*These authors contributed equally: Mathis Nozais, Marie Loosveld; @ Corresponding authors: Dr Delphine Potier and Dr Dominique Payet-Bornet

Link to article : (TO come)

This code is made to be running on Seurat 301v2 Docker. Data and explanation about this code are available at : https://github.com/mathisnozais/MycPten

Any questions on this analysis, please contact Mathis Nozais (nozais@ciml.univ-mrs.fr) or Delphine Potier (potier@ciml.univ-mrs.fr)

[1] “You are starting the analysis from count matrix obtain with CellRanger and Cite-seq-count”

Loading the first experiment

Looking to HTO distribution accross sample :

#HTO distribution
par(mfrow=c(1,1))
par(las=2)
par(mar=c(5,15,3,3))
barplot(rowSums(hto1), main = "Sequenced HTO distribution", horiz=TRUE)

rowSums(hto1)
##   Spleen-MP    Spleen-M Spleen-ctrl    Spleen-P   Thymus-MP    Thymus-M 
##      688432      206663      265412      662165      196262      117402 
## Thymus-ctrl    Thymus-P 
##      156856      562594

Demultiplexing HTO

Demultiplex cells based on HTO enrichment

Demultiplexing results

Cells classification

datatable(as.matrix(table(hashtag1@meta.data$MULTI_ID)),colnames = "Number of cells")

Violinplot (features)

VlnPlot(hashtag1,features = c("nFeature_RNA"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

Violinplot (HTO counts)

VlnPlot(hashtag1,features = c("nCount_HTO"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

tSNEs based on HTO

# Calculate a distance matrix using HTO
hto.dist.mtx <- as.matrix(dist(t(GetAssayData(object = hashtag1, assay = "HTO"))))

# Calculate tSNE embeddings with a distance matrix
hashtag1 <- RunTSNE(hashtag1, distance.matrix = hto.dist.mtx, perplexity = 100)

HTO margin

Tsne<-data.frame(
  tSNE_1 = hashtag1@reductions$tsne@cell.embeddings[,1],
  tSNE_2= hashtag1@reductions$tsne@cell.embeddings[,2],
  gene= hashtag1@meta.data$HTO_margin
)

HTO= hashtag1@meta.data$MULTI_ID
Max=max(hashtag1@meta.data$HTO_margin)
Min=min(hashtag1@meta.data$HTO_margin)
ggplot(Tsne,aes(x=tSNE_1,y=tSNE_2))+geom_point(aes(color=gene,shape=HTO))+
           scale_colour_gradient2(low = "blue",mid="orange",high="red",name="HTO margin",midpoint=(Max+Min)/2)+scale_shape_manual(values = c(15,16,17,18,19,20,21,22,23,24,25))

Ridge plots

Visualize enrichment for selected HTOs with ridge plots

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[1:2],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[3:4],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[5:6],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag1, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[7:8],ncol = 2, group.by = "MULTI_ID")

Sample Information

The analysis will be run on the sample 1.

During the sample loading, we filter cells that do not pass the following filters.
Here are the description of those parameters in the Seurat CreateSeuratObject function:

  • min.genes: Include cells where at least 200 genes are detected
  • min.cells: Include genes with detected expression in at least 3 cells
a <- length(colnames(hashtag1@assays$RNA@data))
print(paste("After those filters, the remaining cell number is", a), quote = FALSE) 
## [1] After those filters, the remaining cell number is 4187
#add Exp1 cell identity
HTO_cr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-ctrl" ))
HTO_ct1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-ctrl" ))
HTO_mr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-M" ))
HTO_mt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-M" ))
HTO_pr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-P" ))
HTO_pt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-P" ))
HTO_pmr1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Spleen-MP" ))
HTO_pmt1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Thymus-MP" ))
HTO_d1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Doublet" ))
HTO_n1 <- row.names(subset(hashtag1@meta.data, MULTI_ID == "Negative" ))

HTO_thymus1 = c(HTO_ct1,HTO_mt1,HTO_pt1,HTO_pmt1)
HTO_spleen1 = c(HTO_cr1,HTO_mr1,HTO_pr1,HTO_pmr1)
HTO_identified1 = c(HTO_thymus1, HTO_spleen1)


# Create a Seurat object without doublet and unassigned cells (remove "negative", "doublet" & "nothing"))
clean.subset1 <- subset(x = hashtag1, cells = HTO_identified1)
VlnPlot(clean.subset1,features = c("nFeature_RNA", "nCount_RNA"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

a <- length(colnames(clean.subset1@assays$RNA@data))
print(paste("After removing doublets and negative cells, the remaining cell number is", a), quote = FALSE) 
## [1] After removing doublets and negative cells, the remaining cell number is 3811

Mitochondrial percentage versus nFeatures

df<-data.frame(multi.id=Seurat1@misc$old_meta_data$MULTI_ID,percent.mito=Seurat1@misc$old_meta_data$percent.mito,nFeature_RNA=Seurat1@misc$old_meta_data$nFeature_RNA)
ggplotly(ggplot(df,aes(x=nFeature_RNA,y=percent.mito,color=multi.id))+geom_point())

UMAP

ggplotly(DimPlot(Seurat1, reduction = "umap", group.by = "MULTI_ID", do.label = TRUE, pt.size = 1))

Loading the second experiment

par(mfrow=c(1,1))
par(las=2)
par(mar=c(5,15,3,3))
barplot(rowSums(hto2), main = "sequenced HTO distribution", horiz=TRUE)

rowSums(hto2)
##   Spleen-MP    Spleen-M Spleen-ctrl    Spleen-P   Thymus-MP    Thymus-M 
##     3569690     1668124      929963     3251282      484276      749822 
## Thymus-ctrl    Thymus-P 
##      310711     1203239

Demultiplexing results

Cells classification

datatable(as.matrix(table(hashtag2@meta.data$MULTI_ID)),colnames = "Number of cells")

Violinplot (features)

VlnPlot(hashtag2,features = c("nFeature_RNA"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

Violin plots (HTO counts)

VlnPlot(hashtag2,features = c("nCount_HTO"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

tSNEs based on HTO

# Calculate a distance matrix using HTO
hto.dist.mtx <- as.matrix(dist(t(GetAssayData(object = hashtag2, assay = "HTO"))))

# Calculate tSNE embeddings with a distance matrix
hashtag2 <- RunTSNE(hashtag2, distance.matrix = hto.dist.mtx, perplexity = 100)
DimPlot(hashtag2, group.by = "MULTI_ID")

HTO margin

Tsne<-data.frame(
  tSNE_1 = hashtag2@reductions$tsne@cell.embeddings[,1],
  tSNE_2= hashtag2@reductions$tsne@cell.embeddings[,2],
  gene= hashtag2@meta.data$HTO_margin
)

HTO= hashtag2@meta.data$MULTI_ID
Max=max(hashtag2@meta.data$HTO_margin)
Min=min(hashtag2@meta.data$HTO_margin)

ggplot(Tsne,aes(x=tSNE_1,y=tSNE_2))+geom_point(aes(color=gene,shape=HTO))+
           scale_colour_gradient2(low = "blue",mid="orange",high="red",name="HTO margin",midpoint=(Max+Min)/2)+scale_shape_manual(values = c(15,16,17,18,19,20,21,22,23,24,25))

Ridge plots

Visualize enrichment for selected HTOs with ridge plots

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[1:2],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[3:4],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[5:6],ncol = 2, group.by = "MULTI_ID")

RidgePlot(hashtag2, assay = "HTO", features = rownames(GetAssayData(hashtag1,assay = "HTO"))[7:8],ncol = 2, group.by = "MULTI_ID")

Sample Information

The analysis will be run on the sample 2.

During the sample loading, we filter cells that do not pass the following filters.

Used parameters in the Seurat CreateSeuratObject function: * min.genes: 3 . Include cells where at least 3 genes are detected * min.cells: 200 . Include genes with detected expression in at least 200 cells

a <-length(colnames(hashtag2@assays$RNA@data))
print(paste("After those filters, the remaining cell number is", a), quote = FALSE) 
## [1] After those filters, the remaining cell number is 12990
#add Exp2 cell identity
HTO_cr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID == "Spleen-ctrl" ))
HTO_ct2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-ctrl" ))
HTO_mr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-M" ))
HTO_mt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-M" ))
HTO_pr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-P" ))
HTO_pt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-P" ))
HTO_pmr2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Spleen-MP" ))
HTO_pmt2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Thymus-MP" ))
HTO_d2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Doublet" ))
HTO_n2 <- row.names(subset(hashtag2@meta.data, MULTI_ID== "Negative" ))

HTO_thymus2 = c(HTO_ct2,HTO_mt2,HTO_pt2,HTO_pmt2)
HTO_spleen2 = c(HTO_cr2,HTO_mr2,HTO_pr2,HTO_pmr2)
HTO_identified2 = c(HTO_thymus2, HTO_spleen2)

# Create a Seurat object without doublet and unassigned cells (remove "negative", "doublet" & "nothing"))
clean.subset2 <- subset(x = hashtag2, cells = HTO_identified2)
VlnPlot(clean.subset2,features = c("nFeature_RNA", "nCount_RNA"),pt.size = 0.1, log = TRUE,  group.by = "MULTI_ID")

a <-length(colnames(clean.subset2@assays$RNA@data))
print(paste("After removing doublets and negative cells, the remaining cell number is", a), quote = FALSE) 
## [1] After removing doublets and negative cells, the remaining cell number is 10309

Adding ADT

# Load in the UMI matrix
umi <- GetAssayData(object = clean.subset2, slot = "counts")

# Load in the ADT count matrix
raw.adt <- Read10X(PATH_ADT_DATA2, gene.column = 1)
adt <- raw.adt[c(1:6),]

rownames(adt) <- c("CD4","CD5","CD8","CD25","CD44","CD69")

#create an empty matrix containing NAs
Cell.list <- colnames(GetAssayData(object = clean.subset2[["RNA"]], slot = "data" ) )
ADT.list <- c(unique(rownames(adt)))
mat.adt <- matrix(nrow = length(ADT.list), ncol = length(Cell.list))
rownames(mat.adt) = ADT.list
colnames(mat.adt) = Cell.list

# Get cell barcodes detected by both RNA and ADT
joint_bcs <- intersect(colnames(umi),colnames(adt))
adt <- as.matrix(adt[,joint_bcs])

# Fill the empty matrix with values when existing
mat.adt[,joint_bcs]<-adt[,joint_bcs]

# Add ADT data as a new assay independent from RNA
clean.subset2[["ADT"]] <- CreateAssayObject(counts = mat.adt[,colnames(clean.subset2)])

# Normalize ADT data, here we use centered log-ratio (CLR) transformation
clean.subset2 <- NormalizeData(clean.subset2, assay = "ADT", normalization.method = "CLR")

#Scale
clean.subset2 <- ScaleData(clean.subset2, assay = "ADT")

ADT list :

print (rownames(adt))

[1] “CD4” “CD5” “CD8” “CD25” “CD44” “CD69”

Mitochondrial percentage versus nFeatures

df<-data.frame(multi.id=Seurat2@misc$old_meta_data$MULTI_ID,percent.mito=Seurat2@misc$old_meta_data$percent.mito,nFeature_RNA=Seurat2@misc$old_meta_data$nFeature_RNA)
ggplotly(ggplot(df,aes(x=nFeature_RNA,y=percent.mito,color=multi.id))+geom_point())

UMAP:

ggplotly(DimPlot(Seurat2, reduction = "umap", group.by = "MULTI_ID", do.label = TRUE, pt.size = 1))

Merging our two experiments

Load separate R object

You can load objects done with the code above. Or our object ?? (link )

Integrating the 2 seurat objects with seurat integration (cca)

a <- length(gene1)
b <- length(gene2)
c <- length(common_genes)

print(paste("We identified ",a," expressed in sample1 and ",b," expressed in sample2.",c,"are in common in this two set and will the integrated in the merged and corrected object."), quote = FALSE) 
## [1] We identified  13750  expressed in sample1 and  15815  expressed in sample2. 13631 are in common in this two set and will the integrated in the merged and corrected object.

UMAP:

Analysis part

Sample Information

The analysis will be run on the replicate 1 and 2.

During the sample loading, we filter cells that do not pass the following filters. We also filter cells that are detected as human/mouse multiplet using their barcodes.
Here are the description of those parameters in the Seurat CreateSeuratObject function:

  • min.genes: Include cells where at least this many genes are detected
  • min.cells: Include genes with detected expression in at least this many cells
a <- length(colnames(exp1.2.integrated))

print(paste("After those filters, and merging MYC_PTEN_01 and MYC_PTEN02 the remaining cell number is",a), quote = FALSE) 
## [1] After those filters, and merging MYC_PTEN_01 and MYC_PTEN02 the remaining cell number is 13912

UMAP and clustering parameter

Merge checking

HTO

Orig.idents

T-cell selection

According to T-cell markers we will exclude Cd3d low clusters: 13 (Bcells), 11, 14, 17 (monocytes/macrophages). According to T-cell markers we will exclude Cd3d/Cd3e low clusters: 11 (Bcells), 13, 17, 18, 19 (monocytes/macrophages), 16, 14 (ILC/NK).

Known RNA B and T markers

re clustering

T-cell umaps

HTO

clustering

END OF PREPROCESSING

We obtain the final object with clustering to start the analysis

Session Info

sessionInfo()
## R version 3.5.3 (2019-03-11)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.5 LTS
## 
## Matrix products: default
## BLAS/LAPACK: /usr/lib/libopenblasp-r0.2.18.so
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=C             
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] knitr_1.23         RColorBrewer_1.1-2 magrittr_1.5      
##  [4] dplyr_0.8.1        DT_0.6.2           gridExtra_2.3     
##  [7] kableExtra_1.1.0   plotly_4.9.0       ggplot2_3.1.1     
## [10] Seurat_3.0.1      
## 
## loaded via a namespace (and not attached):
##   [1] nlme_3.1-140        tsne_0.1-3          bitops_1.0-6       
##   [4] webshot_0.5.1       httr_1.4.0          sctransform_0.2.0  
##   [7] tools_3.5.3         R6_2.4.0            irlba_2.3.3        
##  [10] KernSmooth_2.23-15  lazyeval_0.2.2      colorspace_1.4-1   
##  [13] npsurv_0.4-0        withr_2.1.2         tidyselect_0.2.5   
##  [16] compiler_3.5.3      rvest_0.3.4         xml2_1.2.0         
##  [19] labeling_0.3        caTools_1.17.1.2    scales_1.0.0       
##  [22] lmtest_0.9-37       readr_1.3.1         ggridges_0.5.1     
##  [25] pbapply_1.4-0       stringr_1.4.0       digest_0.6.19      
##  [28] rmarkdown_1.12      R.utils_2.8.0       base64enc_0.1-3    
##  [31] pkgconfig_2.0.2     htmltools_0.3.6     bibtex_0.4.2       
##  [34] highr_0.8           htmlwidgets_1.3     rlang_0.3.4        
##  [37] rstudioapi_0.10     shiny_1.3.2         zoo_1.8-5          
##  [40] jsonlite_1.6        crosstalk_1.0.0     ica_1.0-2          
##  [43] gtools_3.8.1        R.oo_1.22.0         Matrix_1.2-17      
##  [46] Rcpp_1.0.1          munsell_0.5.0       ape_5.3            
##  [49] reticulate_1.12     R.methodsS3_1.7.1   stringi_1.4.3      
##  [52] yaml_2.2.0          gbRd_0.4-11         MASS_7.3-51.4      
##  [55] gplots_3.0.1.1      Rtsne_0.15          plyr_1.8.4         
##  [58] grid_3.5.3          promises_1.0.1      parallel_3.5.3     
##  [61] gdata_2.18.0        listenv_0.7.0       ggrepel_0.8.1      
##  [64] crayon_1.3.4        lattice_0.20-38     cowplot_0.9.4      
##  [67] splines_3.5.3       hms_0.4.2           SDMTools_1.1-221.1 
##  [70] pillar_1.4.0        igraph_1.2.4.1      future.apply_1.2.0 
##  [73] reshape2_1.4.3      codetools_0.2-16    glue_1.3.1         
##  [76] evaluate_0.13       lsei_1.2-0          metap_1.1          
##  [79] data.table_1.12.2   httpuv_1.5.1        png_0.1-7          
##  [82] Rdpack_0.11-0       gtable_0.3.0        RANN_2.6.1         
##  [85] purrr_0.3.2         tidyr_0.8.3         future_1.13.0      
##  [88] assertthat_0.2.1    xfun_0.7            mime_0.6           
##  [91] rsvd_1.0.0          xtable_1.8-4        later_0.8.0        
##  [94] survival_2.44-1.1   viridisLite_0.3.0   tibble_2.1.1       
##  [97] cluster_2.0.9       globals_0.12.4      fitdistrplus_1.0-14
## [100] ROCR_1.0-7

LS0tCnRpdGxlOiAiUmVwb3J0IEV4cGVyaW1lbnRfUHJlcHJvY2Vzc2luZyIKYXV0aG9yOiAiRGVscGhpbmUgUG90aWVyIC8gTWF0aGlzIE5vemFpcyAvIFNhcmFuIFBhbmthZXciCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogY29uc29sZQoKLS0tCgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoubWFpbi1jb250YWluZXIgewogIG1heC13aWR0aDogMTgwMHB4OwogIG1hcmdpbi1sZWZ0OiBhdXRvOwogIG1hcmdpbi1yaWdodDogYXV0bzsKfQo8L3N0eWxlPgoKYGBge3IgZ2xvYmFsLW9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbGlnbiA9ICdjZW50ZXInKQpgYGAKIyBNWUMtZGVmaWNpZW5jeSBpbXBhaXJzIHRoZSBkZXZlbG9wbWVudCBvZiBlZmZlY3Rvci9tZW1vcnkgVCBseW1waG9jeXRlcwoKQXV0aG9ycyA6TWF0aGlzIE5vemFpczFcKiwgTWFyaWUgTG9vc3ZlbGQxLDJcKiwgU2FyYW4gUGFua2FldzEsIENsw6ltZW5jZSBHcm9zamVhbjEsIE5vw6ltaWUgR2VudGlsMSwgSnVsaWUgUXVlc3NhZGExLCBDeXJpbGxlIE1pb25uZXQxLCBEZWxwaGluZSBQb3RpZXIxQCAmIERvbWluaXF1ZSBQYXlldC1Cb3JuZXQxQAoKKlRoZXNlIGF1dGhvcnMgY29udHJpYnV0ZWQgZXF1YWxseTogTWF0aGlzIE5vemFpcywgTWFyaWUgTG9vc3ZlbGQ7IEAgQ29ycmVzcG9uZGluZyBhdXRob3JzOiBEciBEZWxwaGluZSBQb3RpZXIgYW5kIERyIERvbWluaXF1ZSBQYXlldC1Cb3JuZXQKCkxpbmsgdG8gYXJ0aWNsZSA6IChUTyBjb21lKQoKVGhpcyBjb2RlIGlzIG1hZGUgdG8gYmUgcnVubmluZyBvbiBTZXVyYXQgMzAxdjIgRG9ja2VyLiBEYXRhIGFuZCBleHBsYW5hdGlvbiBhYm91dCB0aGlzIGNvZGUgYXJlIGF2YWlsYWJsZSBhdCA6IGh0dHBzOi8vZ2l0aHViLmNvbS9tYXRoaXNub3phaXMvTXljUHRlbgoKQW55IHF1ZXN0aW9ucyBvbiB0aGlzIGFuYWx5c2lzLCBwbGVhc2UgY29udGFjdCBNYXRoaXMgTm96YWlzIChub3phaXNAY2ltbC51bml2LW1ycy5mcikgb3IgRGVscGhpbmUgUG90aWVyIChwb3RpZXJAY2ltbC51bml2LW1ycy5mcikKCgpgYGB7ciBlbnZfbG9hZGluZywgaW5jbHVkZT1GQUxTRX0KIyBMb2FkIHBhY2thZ2VzLCBkYXRhIGFuZCBmdW5jdGlvbnMKbGlicmFyeShTZXVyYXQpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGthYmxlRXh0cmEpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkoRFQpCgojIExvYWQgdGhlIFIgc2NyaXB0cyBjb250YWluaW5nIHRoZSBmdW5jdGlvbnMgdXNlZCBpbiB0aGUgYW5hbHlzaXMKc291cmNlKHBhc3RlMChXT1JLSU5HX0RJUiwiLzAyX1NldXJhdF9hbmFseXNpcy8wMV9TY3JpcHQvV29ya2Zsb3dfZnVuY3Rpb24uUiIpKQoKIyAgUGF0aCB0byB0aGUgZm9sZGVyIHRoYXQgd2lsbCBjb250YWluIG91dHB1dCBvYmplY3RzCk9VVFBVVF9QQVRIIDwtIChwYXN0ZTAoV09SS0lOR19ESVIsIi8wMl9TZXVyYXRfYW5hbHlzaXMvMDJfT3V0cHV0LyIpKQoKIyBTZXQgdGhlIHJhbmRvbSBudW1iZXIgc2VlZApzZXQuc2VlZCgxMjM0KQojIFJlc29sdXRpb24gcGFyYW1ldGVyIGZvciBTZXVyYXQgY2x1c3RlcmluZwpSRVNPTFVUSU9OIDwtIDEKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSxyZXN1bHRzPSdhc2lzJ30KU0FNUExFMSA8LSAicmVwbGljYXRlMSIKU0FNUExFMiA8LSAicmVwbGljYXRlMiIKCmlmKCghIGZpbGUuZXhpc3RzKHBhc3RlMChPVVRQVVRfUEFUSCwgIlNldXJhdF9jbGVhbi1zdWJzZXRfdG9tZXJnZV8iLCBTQU1QTEUxLCAiLlJvYmoiKSkpIHwgKCEgZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldF90b21lcmdlXyIsIFNBTVBMRTIsICIuUm9iaiIpKSkpewpwcmludCgiWW91IGFyZSBzdGFydGluZyB0aGUgYW5hbHlzaXMgZnJvbSBjb3VudCBtYXRyaXggb2J0YWluIHdpdGggQ2VsbFJhbmdlciBhbmQgQ2l0ZS1zZXEtY291bnQiKQpwYXJ0MSA8LSBUUlVFICNleHBlcmltZW50IG9uZSBieSBvbmUKcGFydDIgPC0gVFJVRSAjbWVyZ2luZyAyIG9iamVjdAp9ZWxzZSBpZiggZmlsZS5leGlzdHMocGFzdGUwKE9VVFBVVF9QQVRILCAiVC1TZXVyYXQtbWVyZ2VkX2NsZWFuLXN1YnNldCIsIi5Sb2JqIikpKXsKcHJpbnQoIllvdSBhbHJlYWR5IGhhdmUgdGhlIGZpbmFsIG9iamVjdCBvZiBwcmVwcm9jZXNzaW5nLCB5b3UgY2FuIG5vdyBsYXVjaCB0aGUgRXhwZXJpbWVudF9hbmFseXNpcyBzY3JpcHQiKQpwYXJ0MSA8LSBGQUxTRQpwYXJ0MiA8LSBGQUxTRQp9ZWxzZXsgCnByaW50ICgiWW91IGFyZSBzdGFydGluZyBhbmFseXNpcyBmcm9tIG91ciB0d28gcmVwbGljYXRlIFJvYmogaW4gb3JkZXIgdG8gZG8gdGhlIGludGVncmF0aW9uIikKcGFydDEgPC0gRkFMU0UKcGFydDIgPC0gVFJVRQp9CmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyBMb2FkaW5nIHRoZSBmaXJzdCBleHBlcmltZW50CmBgYAoKCmBgYHtyIHBhdGgxX2xvYWRpbmcsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApfQojIExvYWQgcGF0aCBmb3IgZmlsZXMKUEFUSF9NT1VTRV9EQVRBMSA8LSAocGFzdGUwKFdPUktJTkdfRElSLCIvMDJfU2V1cmF0X2FuYWx5c2lzLzAzX0RhdGEvUmVwbGljYXRlMS9tUk5BLyIpKQpQUk9KRUNUX05BTUUxIDwtIHBhc3RlKCIxMFhfIiwgU0FNUExFMSwgc2VwID0gIiIpClBBVEhfSFRPX0RBVEExIDwtIChwYXN0ZTAoV09SS0lOR19ESVIsIi8wMl9TZXVyYXRfYW5hbHlzaXMvMDNfRGF0YS9SZXBsaWNhdGUxL0hUTy8iKSkKYGBgCgpgYGB7ciBTYW1wbGUxX2xvYWRpbmcsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMgQ3JlYXRlIFNldXJhdCBvYmplY3QgYW5kIGFwcGx5IGZpbHRlcmluZyAgIAojIFJlYWQgMTBYIGRhdGEKbW91c2VfZGF0YTEgPC0gUmVhZDEwWChkYXRhLmRpciA9IFBBVEhfTU9VU0VfREFUQTEpCgojIENyZWF0ZSB0aGUgU2V1cmF0IG9iamVjdCBhbmQgZmlyc3QgZmlsdGVyCk5vdF9wcm9jZXNzZWRfU2V1cmF0X20xIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBtb3VzZV9kYXRhMSwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwLCBwcm9qZWN0ID0gInJlcGxpY2F0ZTEiKQpgYGAKCmBgYHtyIEhUTzFfbG9hZGluZywgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBMb2FkIGluIHRoZSBVTUkgbWF0cml4CnVtaV9zcGFyc2UxIDwtIEdldEFzc2F5RGF0YShvYmplY3QgPSBOb3RfcHJvY2Vzc2VkX1NldXJhdF9tMSwgc2xvdCA9ICJjb3VudHMiKQoKIyBMb2FkIGluIHRoZSBIVE8gY291bnQgbWF0cml4CnJhdy5odG8xIDwtIFJlYWQxMFgoUEFUSF9IVE9fREFUQTEsIGdlbmUuY29sdW1uID0gMSkKaHRvMSA8LSByYXcuaHRvMVtjKDE6OCksXQoKcm93bmFtZXMoaHRvMSkgPC0gYygiU3BsZWVuLU1QIiwiU3BsZWVuLU0iLCJTcGxlZW4tY3RybCIsIlNwbGVlbi1QIiwiVGh5bXVzLU1QIiwiVGh5bXVzLU0iLCJUaHltdXMtY3RybCIsIlRoeW11cy1QIikKCiMgU2VsZWN0IGNlbGwgYmFyY29kZXMgZGV0ZWN0ZWQgYnkgYm90aCBSTkEgYW5kIEhUTwojIEluIHRoZSBleGFtcGxlIGRhdGFzZXRzIHdlIGhhdmUgYWxyZWFkeSBmaWx0ZXJlZCB0aGUgY2VsbHMgZm9yIHlvdSwgYnV0IHBlcmZvcm0gdGhpcyBzdGVwIGZvciBjbGFyaXR5Lgpqb2ludF9iY3MxIDwtIGludGVyc2VjdChjb2xuYW1lcyh1bWlfc3BhcnNlMSksY29sbmFtZXMoaHRvMSkpCgojIFN1YnNldCBSTkEgYW5kIEhUTyBjb3VudHMgYnkgam9pbnQgY2VsbCBiYXJjb2Rlc3VtaV9zcGFyc2UgPC0gcGJtY191bWlfc3BhcnNlWyxqb2ludF9iY3NdCmh0bzEgPC0gYXMubWF0cml4KGh0bzFbLGpvaW50X2JjczFdKQoKIyBDb25maXJtIHRoYXQgdGhlIEhUTyBoYXZlIHRoZSBjb3JyZWN0IG5hbWVzCnByaW50IChyb3duYW1lcyhodG8xKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9Ckxvb2tpbmcgdG8gSFRPIGRpc3RyaWJ1dGlvbiBhY2Nyb3NzIHNhbXBsZSA6CmBgYAoKYGBge3IgSFRPIGRpc3RyaWJ1dGlvbixldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiNIVE8gZGlzdHJpYnV0aW9uCnBhcihtZnJvdz1jKDEsMSkpCnBhcihsYXM9MikKcGFyKG1hcj1jKDUsMTUsMywzKSkKYmFycGxvdChyb3dTdW1zKGh0bzEpLCBtYWluID0gIlNlcXVlbmNlZCBIVE8gZGlzdHJpYnV0aW9uIiwgaG9yaXo9VFJVRSkKcm93U3VtcyhodG8xKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQojIyMgU2V0dXAgc2V1cmF0IG9iamVjdCBhbmQgYWRkIGluIHRoZSBodG8gZGF0YQojIFNldHVwIFNldXJhdCBvYmplY3QKaGFzaHRhZzEgPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KGNvdW50cyA9IHVtaV9zcGFyc2UxWyxqb2ludF9iY3MxXSwgYXNzYXkgPSAiUk5BIiwgcHJvamVjdCA9ICJyZXBsaWNhdGUxIikKCiMgTm9ybWFsaXplIFJOQSBkYXRhIHdpdGggbG9nIG5vcm1hbGl6YXRpb24KaGFzaHRhZzEgPC0gTm9ybWFsaXplRGF0YShoYXNodGFnMSxkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCiMgRmluZCBhbmQgc2NhbGUgdmFyaWFibGUgZ2VuZXMKaGFzaHRhZzEgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoaGFzaHRhZzEsIHBhcnQxLnBsb3QgPSBGLCBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDAsIGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKaGFzaHRhZzEgPC0gU2NhbGVEYXRhKGhhc2h0YWcxLGdlbmVzLnVzZSA9IGhhc2h0YWcxQHZhci5mZWF0dXJlcyxkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMjIyBBZGRpbmcgSFRPIGRhdGEgYXMgYW4gaW5kZXBlbmRlbnQgYXNzYXkKCiMgQWRkIEhUTyBkYXRhIGFzIGEgbmV3IGFzc2F5IGluZGVwZW5kZW50IGZyb20gUk5BCmhhc2h0YWcxW1siSFRPIl1dIDwtIENyZWF0ZUFzc2F5T2JqZWN0KGNvdW50cyA9IGh0bzEpCmhhc2h0YWcxIDwtIFNldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iLHNsb3QgPSAiY291bnRzIixuZXcuZGF0YSA9IGh0bzEpCiMgTm9ybWFsaXplIEhUTyBkYXRhLCBoZXJlIHdlIHVzZSBjZW50ZXJlZCBsb2ctcmF0aW8gKENMUikgdHJhbnNmb3JtYXRpb24KaGFzaHRhZzEgPC0gTm9ybWFsaXplRGF0YShoYXNodGFnMSwgYXNzYXkgPSAiSFRPIixub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJDTFIiLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIERlbXVsdGlwbGV4aW5nIEhUTwpEZW11bHRpcGxleCBjZWxscyBiYXNlZCBvbiBIVE8gZW5yaWNobWVudApgYGAKCmBgYHtyIERlbXVsdGlwbGV4aW5nLCBtZXNzYWdlPUZBTFNFLCBpbmNsdWRlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQoKI1J1biBIVE9kZW11eCBqdXN0IHRvIGdldCB0aGUgSFRPbWF4X0lEIGZpZWQKaGFzaHRhZzEgPC0gSFRPRGVtdXgoaGFzaHRhZzEsIGFzc2F5ID0gIkhUTyIsIHBvc2l0aXZlLnF1YW50aWxlID0gMC45OSwgdmVyYm9zZSA9IEZBTFNFKQojSGVyZSB3ZSB1c2UgdGhlIFNldXJhdCBmdW5jdGlvbiBNVUxUSXNlcURlbXV4KCkgdG8gYXNzaWduIHNpbmdsZSBjZWxscyBiYWNrIHRvIHRoZWlyIHNhbXBsZSBvcmlnaW5zLgpoYXNodGFnMSA8LSBNVUxUSXNlcURlbXV4KGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLGF1dG9UaHJlc2ggPSBUUlVFLCBtYXhpdGVyID0gMTAscXJhbmdlID0gc2VxKGZyb20gPSAwLjEsIHRvID0gMC45LCBieSA9IDAuMDUpLCB2ZXJib3NlID0gVFJVRSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjRGVtdWx0aXBsZXhpbmcgcmVzdWx0cyB7LnRhYnNldH0KYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjI0NlbGxzIGNsYXNzaWZpY2F0aW9uCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpkYXRhdGFibGUoYXMubWF0cml4KHRhYmxlKGhhc2h0YWcxQG1ldGEuZGF0YSRNVUxUSV9JRCkpLGNvbG5hbWVzID0gIk51bWJlciBvZiBjZWxscyIpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIFZpb2xpbnBsb3QgKGZlYXR1cmVzKQpgYGAKCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9ClZsblBsb3QoaGFzaHRhZzEsZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSxwdC5zaXplID0gMC4xLCBsb2cgPSBUUlVFLCAgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIFZpb2xpbnBsb3QgKEhUTyBjb3VudHMpCmBgYAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KVmxuUGxvdChoYXNodGFnMSxmZWF0dXJlcyA9IGMoIm5Db3VudF9IVE8iKSxwdC5zaXplID0gMC4xLCBsb2cgPSBUUlVFLCAgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgdFNORXMgYmFzZWQgb24gSFRPCmBgYAoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KIyBDYWxjdWxhdGUgYSBkaXN0YW5jZSBtYXRyaXggdXNpbmcgSFRPCmh0by5kaXN0Lm10eCA8LSBhcy5tYXRyaXgoZGlzdCh0KEdldEFzc2F5RGF0YShvYmplY3QgPSBoYXNodGFnMSwgYXNzYXkgPSAiSFRPIikpKSkKCiMgQ2FsY3VsYXRlIHRTTkUgZW1iZWRkaW5ncyB3aXRoIGEgZGlzdGFuY2UgbWF0cml4Cmhhc2h0YWcxIDwtIFJ1blRTTkUoaGFzaHRhZzEsIGRpc3RhbmNlLm1hdHJpeCA9IGh0by5kaXN0Lm10eCwgcGVycGxleGl0eSA9IDEwMCkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSxlY2hvPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUpfQpEaW1QbG90KGhhc2h0YWcxLCBncm91cC5ieSA9ICJNVUxUSV9JRCIscmVkdWN0aW9uID0gInRzbmUiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIEhUTyBtYXJnaW4KYGBgCgoKYGBge3IsIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA3LCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KVHNuZTwtZGF0YS5mcmFtZSgKICB0U05FXzEgPSBoYXNodGFnMUByZWR1Y3Rpb25zJHRzbmVAY2VsbC5lbWJlZGRpbmdzWywxXSwKICB0U05FXzI9IGhhc2h0YWcxQHJlZHVjdGlvbnMkdHNuZUBjZWxsLmVtYmVkZGluZ3NbLDJdLAogIGdlbmU9IGhhc2h0YWcxQG1ldGEuZGF0YSRIVE9fbWFyZ2luCikKCkhUTz0gaGFzaHRhZzFAbWV0YS5kYXRhJE1VTFRJX0lECk1heD1tYXgoaGFzaHRhZzFAbWV0YS5kYXRhJEhUT19tYXJnaW4pCk1pbj1taW4oaGFzaHRhZzFAbWV0YS5kYXRhJEhUT19tYXJnaW4pCmdncGxvdChUc25lLGFlcyh4PXRTTkVfMSx5PXRTTkVfMikpK2dlb21fcG9pbnQoYWVzKGNvbG9yPWdlbmUsc2hhcGU9SFRPKSkrCiAgICAgICAgICAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsbWlkPSJvcmFuZ2UiLGhpZ2g9InJlZCIsbmFtZT0iSFRPIG1hcmdpbiIsbWlkcG9pbnQ9KE1heCtNaW4pLzIpK3NjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1KSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBSaWRnZSBwbG90cwoKKipWaXN1YWxpemUgZW5yaWNobWVudCBmb3Igc2VsZWN0ZWQgSFRPcyB3aXRoIHJpZGdlIHBsb3RzKioKYGBgCgoKYGBge3IsIGZpZy5oZWlnaHQgPSA0LCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KUmlkZ2VQbG90KGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbMToyXSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpSaWRnZVBsb3QoaGFzaHRhZzEsIGFzc2F5ID0gIkhUTyIsIGZlYXR1cmVzID0gcm93bmFtZXMoR2V0QXNzYXlEYXRhKGhhc2h0YWcxLGFzc2F5ID0gIkhUTyIpKVszOjRdLG5jb2wgPSAyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpClJpZGdlUGxvdChoYXNodGFnMSwgYXNzYXkgPSAiSFRPIiwgZmVhdHVyZXMgPSByb3duYW1lcyhHZXRBc3NheURhdGEoaGFzaHRhZzEsYXNzYXkgPSAiSFRPIikpWzU6Nl0sbmNvbCA9IDIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKUmlkZ2VQbG90KGhhc2h0YWcxLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbNzo4XSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiMjIFNhbXBsZSBJbmZvcm1hdGlvbgoKVGhlIGFuYWx5c2lzIHdpbGwgYmUgcnVuIG9uIHRoZSBzYW1wbGUgMS4KCkR1cmluZyB0aGUgc2FtcGxlIGxvYWRpbmcsIHdlIGZpbHRlciBjZWxscyB0aGF0IGRvIG5vdCBwYXNzIHRoZSBmb2xsb3dpbmcgZmlsdGVycy4gICAKSGVyZSBhcmUgdGhlIGRlc2NyaXB0aW9uIG9mIHRob3NlIHBhcmFtZXRlcnMgaW4gdGhlIFNldXJhdCAqQ3JlYXRlU2V1cmF0T2JqZWN0KiBmdW5jdGlvbjoKICAKKiBtaW4uZ2VuZXM6IEluY2x1ZGUgY2VsbHMgd2hlcmUgYXQgbGVhc3QgMjAwIGdlbmVzIGFyZSBkZXRlY3RlZAoqIG1pbi5jZWxsczogSW5jbHVkZSBnZW5lcyB3aXRoIGRldGVjdGVkIGV4cHJlc3Npb24gaW4gYXQgbGVhc3QgMyBjZWxscwoKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQphIDwtIGxlbmd0aChjb2xuYW1lcyhoYXNodGFnMUBhc3NheXMkUk5BQGRhdGEpKQpwcmludChwYXN0ZSgiQWZ0ZXIgdGhvc2UgZmlsdGVycywgdGhlIHJlbWFpbmluZyBjZWxsIG51bWJlciBpcyIsIGEpLCBxdW90ZSA9IEZBTFNFKSAKYGBgCgoKCmBgYHtyIGRvdWJsZXRfbmVnYXRpdmVfcmVtb3ZhbCwgcmVzdWx0cz0nYXNpcycsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQojYWRkIEV4cDEgY2VsbCBpZGVudGl0eQpIVE9fY3IxIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICkpCkhUT19jdDEgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtY3RybCIgKSkKSFRPX21yMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NIiApKQpIVE9fbXQxIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzFAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLU0iICkpCkhUT19wcjEgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tUCIgKSkKSFRPX3B0MSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1QIiApKQpIVE9fcG1yMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NUCIgKSkKSFRPX3BtdDEgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJUaHltdXMtTVAiICkpCkhUT19kMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIkRvdWJsZXQiICkpCkhUT19uMSA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIk5lZ2F0aXZlIiApKQoKSFRPX3RoeW11czEgPSBjKEhUT19jdDEsSFRPX210MSxIVE9fcHQxLEhUT19wbXQxKQpIVE9fc3BsZWVuMSA9IGMoSFRPX2NyMSxIVE9fbXIxLEhUT19wcjEsSFRPX3BtcjEpCkhUT19pZGVudGlmaWVkMSA9IGMoSFRPX3RoeW11czEsIEhUT19zcGxlZW4xKQoKCiMgQ3JlYXRlIGEgU2V1cmF0IG9iamVjdCB3aXRob3V0IGRvdWJsZXQgYW5kIHVuYXNzaWduZWQgY2VsbHMgKHJlbW92ZSAibmVnYXRpdmUiLCAiZG91YmxldCIgJiAibm90aGluZyIpKQpjbGVhbi5zdWJzZXQxIDwtIHN1YnNldCh4ID0gaGFzaHRhZzEsIGNlbGxzID0gSFRPX2lkZW50aWZpZWQxKQpWbG5QbG90KGNsZWFuLnN1YnNldDEsZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge3IsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KYSA8LSBsZW5ndGgoY29sbmFtZXMoY2xlYW4uc3Vic2V0MUBhc3NheXMkUk5BQGRhdGEpKQpwcmludChwYXN0ZSgiQWZ0ZXIgcmVtb3ZpbmcgZG91YmxldHMgYW5kIG5lZ2F0aXZlIGNlbGxzLCB0aGUgcmVtYWluaW5nIGNlbGwgbnVtYmVyIGlzIiwgYSksIHF1b3RlID0gRkFMU0UpIApgYGAKCgpgYGB7ciBwcm9jZXNzaW5nXzEsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMgT0JKRUNUIE9ORSBQUk9DRVNTSU5HIEFORCBTQVZFCiMxLSBRQyAKU2V1cmF0MSA8LSBRQ19mdW5jdGlvbl9taXRvX3RocmVzaG9sZChTZXVyYXQgPSBjbGVhbi5zdWJzZXQxLCBtaXRvX3RocmVzaG9sZCA9IDAuMSwgZG9fcGxvdCA9IEZBTFNFKQogIAojMi0gRmluZCB2YXJpYWJsZSBnZW5lcwpTZXVyYXQxIDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IFNldXJhdDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzYXkgPSAiUk5BIiwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCBkby5wbG90PVRSVUUpCgpTZXVyYXQxIDwtIFNjYWxlRGF0YShTZXVyYXQxLCAKICAgICAgICAgICAgICAgICAgICAgICBhc3NheT0iUk5BIiwKICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICNkby5zY2FsZSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICBkby5jZW50ZXIgPSBUUlVFKQogIApTZXVyYXQxIDwtIFJ1blBDQShvYmplY3QgPSBTZXVyYXQxLAogICAgICAgICAgICAgICAgICAgIGFzc2F5ID0gIlJOQSIsCiAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCAjaWYgVFJVRSBwcmludCB0aGUgdG9wIGdlbmVzIGZvciBlYWNoIFBDCiAgICAgICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAgVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBTZXVyYXQxKSwgCiAgICAgICAgICAgICAgICAgICAgc2VlZC51c2UgPSAxMjM0LAogICAgICAgICAgICAgICAgICAgIG5wY3MgPSA1MCkgIyBzdXIgbGVzIDUwIHByZW1pZXJlcyBjb21wb3NhbnRlcwogIApFbGJvd1Bsb3QoU2V1cmF0MSwgbmRpbXMgPSA1MCwgcmVkdWN0aW9uID0gInBjYSIpCiAgClNldXJhdDEgPC0gUHJvamVjdERpbShvYmplY3QgPSBTZXVyYXQxLAogICAgICAgICAgICAgICAgICAgICAgICBuZmVhdHVyZXMucHJpbnQgPSAyMCwKICAgICAgICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTApCiAgClNldXJhdDEgPC0gUnVuVFNORShvYmplY3QgPSBTZXVyYXQxLAogICAgICAgICAgICAgICAgICAgICBkby5mYXN0ID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICAgIHNlZWQudXNlID0gMTIzNCwKICAgICAgICAgICAgICAgICAgICAgZGltcyA9IDE6MjAsICMgVXNlcyAyMCBmaXJzdCBQQ3MKICAgICAgICAgICAgICAgICAgICAgcGVycGxleGl0eSA9IDQwKQogIApTZXVyYXQxIDwtIEZpbmROZWlnaGJvcnMob2JqZWN0ID0gU2V1cmF0MSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjIwICwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcmNlLnJlY2FsYyA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWR1Y3Rpb24gPSAicGNhIikKClNldXJhdDEgPC0gRmluZENsdXN0ZXJzKG9iamVjdCA9IFNldXJhdDEsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdXRpb24gPSBSRVNPTFVUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpClNldXJhdDEgPC0gUnVuVU1BUChvYmplY3QgPSBTZXVyYXQxLCByZWR1Y3Rpb24gPSAicGNhIiwgc2VlZC51c2UgPSAxMjM0LCBkaW1zID0gMToyMCkKICAKc2F2ZShTZXVyYXQxLCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldF90b21lcmdlXyIsIFNBTVBMRTEsICIuUm9iaiIpKQpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIE1pdG9jaG9uZHJpYWwgcGVyY2VudGFnZSB2ZXJzdXMgbkZlYXR1cmVzCmBgYAoKYGBge3IgbWl0b192c19uZmVhdHVyZXMsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpkZjwtZGF0YS5mcmFtZShtdWx0aS5pZD1TZXVyYXQxQG1pc2Mkb2xkX21ldGFfZGF0YSRNVUxUSV9JRCxwZXJjZW50Lm1pdG89U2V1cmF0MUBtaXNjJG9sZF9tZXRhX2RhdGEkcGVyY2VudC5taXRvLG5GZWF0dXJlX1JOQT1TZXVyYXQxQG1pc2Mkb2xkX21ldGFfZGF0YSRuRmVhdHVyZV9STkEpCmdncGxvdGx5KGdncGxvdChkZixhZXMoeD1uRmVhdHVyZV9STkEseT1wZXJjZW50Lm1pdG8sY29sb3I9bXVsdGkuaWQpKStnZW9tX3BvaW50KCkpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgVU1BUApgYGAKCmBgYHtyIFVNQVBfSFRPX3NldXJhdF8xLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQxLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIiwgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMSkpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIExvYWRpbmcgdGhlIHNlY29uZCBleHBlcmltZW50CmBgYAoKCmBgYHtyIHBhdGgyX2xvYWRpbmcsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiMgTG9hZCBwYXRoIGZvciBmaWxlcwpQQVRIX01PVVNFX0RBVEEyIDwtIChwYXN0ZTAoV09SS0lOR19ESVIsIi8wMl9TZXVyYXRfYW5hbHlzaXMvMDNfRGF0YS9SZXBsaWNhdGUyL21STkEiKSkKUFJPSkVDVF9OQU1FMiA8LSBwYXN0ZSgiMTBYXyIsIFNBTVBMRTIsIHNlcCA9ICIiKQpQQVRIX0hUT19EQVRBMiA8LSAocGFzdGUwKFdPUktJTkdfRElSLCIvMDJfU2V1cmF0X2FuYWx5c2lzLzAzX0RhdGEvUmVwbGljYXRlMi9IVE8iKSkKUEFUSF9BRFRfREFUQTIgPC0gKHBhc3RlMChXT1JLSU5HX0RJUiwiLzAyX1NldXJhdF9hbmFseXNpcy8wM19EYXRhL1JlcGxpY2F0ZTIvQURUIikpCmBgYAoKYGBge3IgU2FtcGxlX2xvYWRpbmdfMiwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBDcmVhdGUgU2V1cmF0IG9iamVjdCBhbmQgYXBwbHkgZmlsdGVyaW5nICAgCiMgUmVhZCAxMFggZGF0YQptb3VzZV9kYXRhMiA8LSBSZWFkMTBYKGRhdGEuZGlyID0gUEFUSF9NT1VTRV9EQVRBMikKCgojIENyZWF0ZSB0aGUgU2V1cmF0IG9iamVjdCBhbmQgZmlyc3QgZmlsdGVyCk5vdF9wcm9jZXNzZWRfU2V1cmF0X20yIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSBtb3VzZV9kYXRhMiwgbWluLmNlbGxzID0gMywgbWluLmZlYXR1cmVzID0gMjAwLCBwcm9qZWN0ID0gInJlcGxpY2F0ZTIiKQpgYGAKCmBgYHtyICwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBMb2FkIGluIHRoZSBVTUkgbWF0cml4CnVtaV9zcGFyc2UyIDwtIEdldEFzc2F5RGF0YShvYmplY3QgPSBOb3RfcHJvY2Vzc2VkX1NldXJhdF9tMiwgc2xvdCA9ICJjb3VudHMiKQoKIyBMb2FkIGluIHRoZSBIVE8gY291bnQgbWF0cml4CnJhdy5odG8yIDwtIFJlYWQxMFgoUEFUSF9IVE9fREFUQTIsIGdlbmUuY29sdW1uID0gMSkKaHRvMiA8LSByYXcuaHRvMltjKDE6OCksXQoKcm93bmFtZXMoaHRvMikgPC0gYygiU3BsZWVuLU1QIiwiU3BsZWVuLU0iLCJTcGxlZW4tY3RybCIsIlNwbGVlbi1QIiwiVGh5bXVzLU1QIiwiVGh5bXVzLU0iLCJUaHltdXMtY3RybCIsIlRoeW11cy1QIikKCiMgU2VsZWN0IGNlbGwgYmFyY29kZXMgZGV0ZWN0ZWQgYnkgYm90aCBSTkEgYW5kIEhUTwpqb2ludF9iY3MyIDwtIGludGVyc2VjdChjb2xuYW1lcyh1bWlfc3BhcnNlMiksY29sbmFtZXMoaHRvMikpCmh0bzIgPC0gYXMubWF0cml4KGh0bzJbLGpvaW50X2JjczJdKQoKIyBDb25maXJtIHRoYXQgdGhlIEhUTyBoYXZlIHRoZSBjb3JyZWN0IG5hbWVzCnByaW50IChyb3duYW1lcyhodG8yKSkKYGBgCgpgYGB7cixldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CnBhcihtZnJvdz1jKDEsMSkpCnBhcihsYXM9MikKcGFyKG1hcj1jKDUsMTUsMywzKSkKYmFycGxvdChyb3dTdW1zKGh0bzIpLCBtYWluID0gInNlcXVlbmNlZCBIVE8gZGlzdHJpYnV0aW9uIiwgaG9yaXo9VFJVRSkKCnJvd1N1bXMoaHRvMikKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyMjIFNldHVwIHNldXJhdCBvYmplY3QgYW5kIGFkZCBpbiB0aGUgaHRvIGRhdGEKIyBTZXR1cCBTZXVyYXQgb2JqZWN0Cmhhc2h0YWcyIDwtIENyZWF0ZVNldXJhdE9iamVjdChjb3VudHMgPSB1bWlfc3BhcnNlMlssam9pbnRfYmNzMiBdLCBhc3NheSA9ICJSTkEiLCBwcm9qZWN0ID0gInJlcGxpY2F0ZTIiKQoKIyBOb3JtYWxpemUgUk5BIGRhdGEgd2l0aCBsb2cgbm9ybWFsaXphdGlvbgpoYXNodGFnMiA8LSBOb3JtYWxpemVEYXRhKGhhc2h0YWcyLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKIyBGaW5kIGFuZCBzY2FsZSB2YXJpYWJsZSBnZW5lcwpoYXNodGFnMiA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhoYXNodGFnMixkby5wbG90ID0gRixzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDAsIGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKaGFzaHRhZzIgPC0gU2NhbGVEYXRhKGhhc2h0YWcyLGdlbmVzLnVzZSA9IGhhc2h0YWcyQGFzc2F5cyRSTkFAdmFyLmZlYXR1cmVzLGRpc3BsYXkucHJvZ3Jlc3MgPSBGQUxTRSkKYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyMjIEFkZGluZyBIVE8gZGF0YSBhcyBhbiBpbmRlcGVuZGVudCBhc3NheQojIEFkZCBIVE8gZGF0YSBhcyBhIG5ldyBhc3NheSBpbmRlcGVuZGVudCBmcm9tIFJOQQpoYXNodGFnMltbIkhUTyJdXSA8LSBDcmVhdGVBc3NheU9iamVjdChjb3VudHMgPSBodG8yKQpoYXNodGFnMiA8LSBTZXRBc3NheURhdGEoaGFzaHRhZzIsYXNzYXkgPSAiSFRPIixzbG90ID0gImNvdW50cyIsbmV3LmRhdGEgPSBodG8yKQojIE5vcm1hbGl6ZSBIVE8gZGF0YSwgaGVyZSB3ZSB1c2UgY2VudGVyZWQgbG9nLXJhdGlvIChDTFIpIHRyYW5zZm9ybWF0aW9uCmhhc2h0YWcyIDwtIE5vcm1hbGl6ZURhdGEoaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIsbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiQ0xSIixkaXNwbGF5LnByb2dyZXNzID0gRkFMU0UpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIGluY2x1ZGU9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSl9CiNSdW4gSFRPZGVtdXgganVzdCB0byBnZXQgdGhlIEhUT19tYXhJRCBmaWVsZApoYXNodGFnMiA8LSBIVE9EZW11eChoYXNodGFnMiwgYXNzYXkgPSAiSFRPIiwgcG9zaXRpdmUucXVhbnRpbGUgPSAwLjk5LCB2ZXJib3NlID0gRkFMU0UpCiNEZW11bHRpcGxleCBjZWxscyBiYXNlZCBvbiBIVE8gZW5yaWNobWVudApoYXNodGFnMiA8LSBNVUxUSXNlcURlbXV4KGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLGF1dG9UaHJlc2ggPSBUUlVFLCBtYXhpdGVyID0gMTAscXJhbmdlID0gc2VxKGZyb20gPSAwLjEsIHRvID0gMC45LCBieSA9IDAuMDUpLCB2ZXJib3NlID0gVFJVRSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjRGVtdWx0aXBsZXhpbmcgcmVzdWx0cyB7LnRhYnNldH0KYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjI0NlbGxzIGNsYXNzaWZpY2F0aW9uCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpkYXRhdGFibGUoYXMubWF0cml4KHRhYmxlKGhhc2h0YWcyQG1ldGEuZGF0YSRNVUxUSV9JRCkpLGNvbG5hbWVzID0gIk51bWJlciBvZiBjZWxscyIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgVmlvbGlucGxvdCAoZmVhdHVyZXMpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpWbG5QbG90KGhhc2h0YWcyLGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIikscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBWaW9saW4gcGxvdHMgKEhUTyBjb3VudHMpCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpWbG5QbG90KGhhc2h0YWcyLGZlYXR1cmVzID0gYygibkNvdW50X0hUTyIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyB0U05FcyBiYXNlZCBvbiBIVE8KYGBgCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiMgQ2FsY3VsYXRlIGEgZGlzdGFuY2UgbWF0cml4IHVzaW5nIEhUTwpodG8uZGlzdC5tdHggPC0gYXMubWF0cml4KGRpc3QodChHZXRBc3NheURhdGEob2JqZWN0ID0gaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIpKSkpCgojIENhbGN1bGF0ZSB0U05FIGVtYmVkZGluZ3Mgd2l0aCBhIGRpc3RhbmNlIG1hdHJpeApoYXNodGFnMiA8LSBSdW5UU05FKGhhc2h0YWcyLCBkaXN0YW5jZS5tYXRyaXggPSBodG8uZGlzdC5tdHgsIHBlcnBsZXhpdHkgPSAxMDApCmBgYAoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpEaW1QbG90KGhhc2h0YWcyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyMgSFRPIG1hcmdpbgpgYGAKCgpgYGB7ciwgZmlnLndpZHRoID0gOCwgZmlnLmhlaWdodCA9IDcsIG1lc3NhZ2U9RkFMU0UsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpUc25lPC1kYXRhLmZyYW1lKAogIHRTTkVfMSA9IGhhc2h0YWcyQHJlZHVjdGlvbnMkdHNuZUBjZWxsLmVtYmVkZGluZ3NbLDFdLAogIHRTTkVfMj0gaGFzaHRhZzJAcmVkdWN0aW9ucyR0c25lQGNlbGwuZW1iZWRkaW5nc1ssMl0sCiAgZ2VuZT0gaGFzaHRhZzJAbWV0YS5kYXRhJEhUT19tYXJnaW4KKQoKSFRPPSBoYXNodGFnMkBtZXRhLmRhdGEkTVVMVElfSUQKTWF4PW1heChoYXNodGFnMkBtZXRhLmRhdGEkSFRPX21hcmdpbikKTWluPW1pbihoYXNodGFnMkBtZXRhLmRhdGEkSFRPX21hcmdpbikKCmdncGxvdChUc25lLGFlcyh4PXRTTkVfMSx5PXRTTkVfMikpK2dlb21fcG9pbnQoYWVzKGNvbG9yPWdlbmUsc2hhcGU9SFRPKSkrCiAgICAgICAgICAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsbWlkPSJvcmFuZ2UiLGhpZ2g9InJlZCIsbmFtZT0iSFRPIG1hcmdpbiIsbWlkcG9pbnQ9KE1heCtNaW4pLzIpK3NjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1KSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBSaWRnZSBwbG90cwoKKipWaXN1YWxpemUgZW5yaWNobWVudCBmb3Igc2VsZWN0ZWQgSFRPcyB3aXRoIHJpZGdlIHBsb3RzKioKYGBgCgoKYGBge3IsIGZpZy5oZWlnaHQgPSA0LCBtZXNzYWdlPUZBTFNFLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KUmlkZ2VQbG90KGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbMToyXSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpSaWRnZVBsb3QoaGFzaHRhZzIsIGFzc2F5ID0gIkhUTyIsIGZlYXR1cmVzID0gcm93bmFtZXMoR2V0QXNzYXlEYXRhKGhhc2h0YWcxLGFzc2F5ID0gIkhUTyIpKVszOjRdLG5jb2wgPSAyLCBncm91cC5ieSA9ICJNVUxUSV9JRCIpClJpZGdlUGxvdChoYXNodGFnMiwgYXNzYXkgPSAiSFRPIiwgZmVhdHVyZXMgPSByb3duYW1lcyhHZXRBc3NheURhdGEoaGFzaHRhZzEsYXNzYXkgPSAiSFRPIikpWzU6Nl0sbmNvbCA9IDIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKUmlkZ2VQbG90KGhhc2h0YWcyLCBhc3NheSA9ICJIVE8iLCBmZWF0dXJlcyA9IHJvd25hbWVzKEdldEFzc2F5RGF0YShoYXNodGFnMSxhc3NheSA9ICJIVE8iKSlbNzo4XSxuY29sID0gMiwgZ3JvdXAuYnkgPSAiTVVMVElfSUQiKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CgojIyBTYW1wbGUgSW5mb3JtYXRpb24KClRoZSBhbmFseXNpcyB3aWxsIGJlIHJ1biBvbiB0aGUgc2FtcGxlIDIuCgpEdXJpbmcgdGhlIHNhbXBsZSBsb2FkaW5nLCB3ZSBmaWx0ZXIgY2VsbHMgdGhhdCBkbyBub3QgcGFzcyB0aGUgZm9sbG93aW5nIGZpbHRlcnMuCgpVc2VkIHBhcmFtZXRlcnMgaW4gdGhlIFNldXJhdCAqQ3JlYXRlU2V1cmF0T2JqZWN0KiBmdW5jdGlvbjoKKiBtaW4uZ2VuZXM6IDMgLiBJbmNsdWRlIGNlbGxzIHdoZXJlIGF0IGxlYXN0IDMgZ2VuZXMgYXJlIGRldGVjdGVkCiogbWluLmNlbGxzOiAyMDAgLiBJbmNsdWRlIGdlbmVzIHdpdGggZGV0ZWN0ZWQgZXhwcmVzc2lvbiBpbiBhdCBsZWFzdCAyMDAgY2VsbHMKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQphIDwtbGVuZ3RoKGNvbG5hbWVzKGhhc2h0YWcyQGFzc2F5cyRSTkFAZGF0YSkpCnByaW50KHBhc3RlKCJBZnRlciB0aG9zZSBmaWx0ZXJzLCB0aGUgcmVtYWluaW5nIGNlbGwgbnVtYmVyIGlzIiwgYSksIHF1b3RlID0gRkFMU0UpIApgYGAKCmBgYHtyIGNlbGxfc2VsZWN0XzIsIHJlc3VsdHM9J2FzaXMnLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KI2FkZCBFeHAyIGNlbGwgaWRlbnRpdHkKSFRPX2NyMiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1jdHJsIiApKQpIVE9fY3QyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtY3RybCIgKSkKSFRPX21yMiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiU3BsZWVuLU0iICkpCkhUT19tdDIgPC0gcm93Lm5hbWVzKHN1YnNldChoYXNodGFnMkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlRoeW11cy1NIiApKQpIVE9fcHIyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJTcGxlZW4tUCIgKSkKSFRPX3B0MiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiVGh5bXVzLVAiICkpCkhUT19wbXIyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJTcGxlZW4tTVAiICkpCkhUT19wbXQyIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtTVAiICkpCkhUT19kMiA8LSByb3cubmFtZXMoc3Vic2V0KGhhc2h0YWcyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiRG91YmxldCIgKSkKSFRPX24yIDwtIHJvdy5uYW1lcyhzdWJzZXQoaGFzaHRhZzJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJOZWdhdGl2ZSIgKSkKCkhUT190aHltdXMyID0gYyhIVE9fY3QyLEhUT19tdDIsSFRPX3B0MixIVE9fcG10MikKSFRPX3NwbGVlbjIgPSBjKEhUT19jcjIsSFRPX21yMixIVE9fcHIyLEhUT19wbXIyKQpIVE9faWRlbnRpZmllZDIgPSBjKEhUT190aHltdXMyLCBIVE9fc3BsZWVuMikKCiMgQ3JlYXRlIGEgU2V1cmF0IG9iamVjdCB3aXRob3V0IGRvdWJsZXQgYW5kIHVuYXNzaWduZWQgY2VsbHMgKHJlbW92ZSAibmVnYXRpdmUiLCAiZG91YmxldCIgJiAibm90aGluZyIpKQpjbGVhbi5zdWJzZXQyIDwtIHN1YnNldCh4ID0gaGFzaHRhZzIsIGNlbGxzID0gSFRPX2lkZW50aWZpZWQyKQpWbG5QbG90KGNsZWFuLnN1YnNldDIsZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIpLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJNVUxUSV9JRCIpCmBgYAoKYGBge3IsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KYSA8LWxlbmd0aChjb2xuYW1lcyhjbGVhbi5zdWJzZXQyQGFzc2F5cyRSTkFAZGF0YSkpCnByaW50KHBhc3RlKCJBZnRlciByZW1vdmluZyBkb3VibGV0cyBhbmQgbmVnYXRpdmUgY2VsbHMsIHRoZSByZW1haW5pbmcgY2VsbCBudW1iZXIgaXMiLCBhKSwgcXVvdGUgPSBGQUxTRSkgCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBBZGRpbmcgQURUCmBgYAoKCmBgYHtyIGxvYWRfYWR0LCAgbWVzc2FnZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89aWYgKHBhcnQxKSBUUlVFIGVsc2UgRkFMU0V9CiMgTG9hZCBpbiB0aGUgVU1JIG1hdHJpeAp1bWkgPC0gR2V0QXNzYXlEYXRhKG9iamVjdCA9IGNsZWFuLnN1YnNldDIsIHNsb3QgPSAiY291bnRzIikKCiMgTG9hZCBpbiB0aGUgQURUIGNvdW50IG1hdHJpeApyYXcuYWR0IDwtIFJlYWQxMFgoUEFUSF9BRFRfREFUQTIsIGdlbmUuY29sdW1uID0gMSkKYWR0IDwtIHJhdy5hZHRbYygxOjYpLF0KCnJvd25hbWVzKGFkdCkgPC0gYygiQ0Q0IiwiQ0Q1IiwiQ0Q4IiwiQ0QyNSIsIkNENDQiLCJDRDY5IikKCiNjcmVhdGUgYW4gZW1wdHkgbWF0cml4IGNvbnRhaW5pbmcgTkFzCkNlbGwubGlzdCA8LSBjb2xuYW1lcyhHZXRBc3NheURhdGEob2JqZWN0ID0gY2xlYW4uc3Vic2V0MltbIlJOQSJdXSwgc2xvdCA9ICJkYXRhIiApICkKQURULmxpc3QgPC0gYyh1bmlxdWUocm93bmFtZXMoYWR0KSkpCm1hdC5hZHQgPC0gbWF0cml4KG5yb3cgPSBsZW5ndGgoQURULmxpc3QpLCBuY29sID0gbGVuZ3RoKENlbGwubGlzdCkpCnJvd25hbWVzKG1hdC5hZHQpID0gQURULmxpc3QKY29sbmFtZXMobWF0LmFkdCkgPSBDZWxsLmxpc3QKCiMgR2V0IGNlbGwgYmFyY29kZXMgZGV0ZWN0ZWQgYnkgYm90aCBSTkEgYW5kIEFEVApqb2ludF9iY3MgPC0gaW50ZXJzZWN0KGNvbG5hbWVzKHVtaSksY29sbmFtZXMoYWR0KSkKYWR0IDwtIGFzLm1hdHJpeChhZHRbLGpvaW50X2Jjc10pCgojIEZpbGwgdGhlIGVtcHR5IG1hdHJpeCB3aXRoIHZhbHVlcyB3aGVuIGV4aXN0aW5nCm1hdC5hZHRbLGpvaW50X2Jjc108LWFkdFssam9pbnRfYmNzXQoKIyBBZGQgQURUIGRhdGEgYXMgYSBuZXcgYXNzYXkgaW5kZXBlbmRlbnQgZnJvbSBSTkEKY2xlYW4uc3Vic2V0MltbIkFEVCJdXSA8LSBDcmVhdGVBc3NheU9iamVjdChjb3VudHMgPSBtYXQuYWR0Wyxjb2xuYW1lcyhjbGVhbi5zdWJzZXQyKV0pCgojIE5vcm1hbGl6ZSBBRFQgZGF0YSwgaGVyZSB3ZSB1c2UgY2VudGVyZWQgbG9nLXJhdGlvIChDTFIpIHRyYW5zZm9ybWF0aW9uCmNsZWFuLnN1YnNldDIgPC0gTm9ybWFsaXplRGF0YShjbGVhbi5zdWJzZXQyLCBhc3NheSA9ICJBRFQiLCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJDTFIiKQoKI1NjYWxlCmNsZWFuLnN1YnNldDIgPC0gU2NhbGVEYXRhKGNsZWFuLnN1YnNldDIsIGFzc2F5ID0gIkFEVCIpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQpBRFQgbGlzdCA6CmBgYAoKCmBgYHtyICwgcmVzdWx0cz0nYXNpcycsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpwcmludCAocm93bmFtZXMoYWR0KSkKYGBgCgpgYGB7ciBTaWduaWZpY2FudF9QQywgaW5jbHVkZT1GQUxTRSxldmFsPShwYXJ0MSA9PSBUUlVFKX0KIyBPQkpFQ1QgVFdPIFBST0NFU1NJTkcgQU5EIFNBVkUKIzEtIFFDIApTZXVyYXQyIDwtIFFDX2Z1bmN0aW9uX21pdG9fdGhyZXNob2xkKFNldXJhdCA9IGNsZWFuLnN1YnNldDIsIG1pdG9fdGhyZXNob2xkID0gMC4xLCBkb19wbG90ID0gRkFMU0UpCiAgCiMyLSBGaW5kIHZhcmlhYmxlIGdlbmVzClNldXJhdDIgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gU2V1cmF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJSTkEiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLCB2ZXJib3NlID0gRkFMU0UsIGRvLnBsb3Q9VFJVRSkKICAKU2V1cmF0MiA8LSBTY2FsZURhdGEoU2V1cmF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgYXNzYXk9IlJOQSIsCiAgICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAjZG8uc2NhbGUgPSBGQUxTRSwgCiAgICAgICAgICAgICAgICAgICAgICAgZG8uY2VudGVyID0gVFJVRSkKICAKU2V1cmF0MiA8LSBSdW5QQ0Eob2JqZWN0ID0gU2V1cmF0MiwKICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJSTkEiLAogICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwgI2lmIFRSVUUgcHJpbnQgdGhlIHRvcCBnZW5lcyBmb3IgZWFjaCBQQwogICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gIFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gU2V1cmF0MiksIAogICAgICAgICAgICAgICAgICAgIHNlZWQudXNlID0gMTIzNCwKICAgICAgICAgICAgICAgICAgICBucGNzID0gNTApIAogIApFbGJvd1Bsb3QoU2V1cmF0MiwgbmRpbXMgPSA0MCwgcmVkdWN0aW9uID0gInBjYSIpCiAgClNldXJhdCA8LSBQcm9qZWN0RGltKG9iamVjdCA9IFNldXJhdDIsCiAgICAgICAgICAgICAgICAgICAgICAgbmZlYXR1cmVzLnByaW50ID0gMjAsCiAgICAgICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTApCgpTZXVyYXQyIDwtIFJ1blRTTkUob2JqZWN0ID0gU2V1cmF0MiwKICAgICAgICAgICAgICAgICAgICAgZG8uZmFzdCA9IFRSVUUsIAogICAgICAgICAgICAgICAgICAgICBzZWVkLnVzZSA9IDEyMzQsCiAgICAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjIwLCAKICAgICAgICAgICAgICAgICAgICAgcGVycGxleGl0eSA9IDQwKQogIApTZXVyYXQyIDwtIEZpbmROZWlnaGJvcnMob2JqZWN0ID0gU2V1cmF0MiwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkaW1zID0gMToyMCAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JjZS5yZWNhbGMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVkdWN0aW9uID0gInBjYSIpCiAgClNldXJhdDIgPC0gRmluZENsdXN0ZXJzKG9iamVjdCA9IFNldXJhdDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdXRpb24gPSBSRVNPTFVUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgIHZlcmJvc2UgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpCiAgClNldXJhdDIgPC0gUnVuVU1BUChvYmplY3QgPSBTZXVyYXQyLCByZWR1Y3Rpb24gPSAicGNhIiwgc2VlZC51c2UgPSAxMjM0LCBkaW1zID0gMToyMCkKICAKc2F2ZShTZXVyYXQyLCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldF90b21lcmdlXyIsIFNBTVBMRTIsICIuUm9iaiIpKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MSA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgTWl0b2Nob25kcmlhbCBwZXJjZW50YWdlIHZlcnN1cyBuRmVhdHVyZXMKYGBgCgpgYGB7ciBtaXRvX3ZzX25mZWF0dXJlczIsZXZhbD0ocGFydDEgPT0gVFJVRSApLCBlY2hvPWlmIChwYXJ0MSkgVFJVRSBlbHNlIEZBTFNFfQpkZjwtZGF0YS5mcmFtZShtdWx0aS5pZD1TZXVyYXQyQG1pc2Mkb2xkX21ldGFfZGF0YSRNVUxUSV9JRCxwZXJjZW50Lm1pdG89U2V1cmF0MkBtaXNjJG9sZF9tZXRhX2RhdGEkcGVyY2VudC5taXRvLG5GZWF0dXJlX1JOQT1TZXVyYXQyQG1pc2Mkb2xkX21ldGFfZGF0YSRuRmVhdHVyZV9STkEpCmdncGxvdGx5KGdncGxvdChkZixhZXMoeD1uRmVhdHVyZV9STkEseT1wZXJjZW50Lm1pdG8sY29sb3I9bXVsdGkuaWQpKStnZW9tX3BvaW50KCkpCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBVTUFQOgpgYGAKCmBgYHtyIFVNQVBfSFRPX3NldXJhdF8yLGV2YWw9KHBhcnQxID09IFRSVUUgKSwgZWNobz1pZiAocGFydDEpIFRSVUUgZWxzZSBGQUxTRX0KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQyLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIiwgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMSkpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KI01lcmdpbmcgb3VyIHR3byBleHBlcmltZW50cwpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgTG9hZCBzZXBhcmF0ZSBSIG9iamVjdApZb3UgY2FuIGxvYWQgb2JqZWN0cyBkb25lIHdpdGggdGhlIGNvZGUgYWJvdmUuCk9yIG91ciBvYmplY3QgPz8gKGxpbmsgKQpgYGAKCmBgYHtyIFNhbXBsZXNfbG9hZGluZyxldmFsPShwYXJ0MiA9PSBUUlVFICkgLGluY2x1ZGU9RkFMU0V9CiNsb2FkIGFsbCBzZXVyYXQgb2JqZWN0cyBidWlsdCBwcmV2aW91c2x5CmxvYWQocGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0X2NsZWFuLXN1YnNldF90b21lcmdlXyIsIFNBTVBMRTEsICIuUm9iaiIpKQpsb2FkKHBhc3RlMChPVVRQVVRfUEFUSCwgIlNldXJhdF9jbGVhbi1zdWJzZXRfdG9tZXJnZV8iLCBTQU1QTEUyLCAiLlJvYmoiKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIEludGVncmF0aW5nIHRoZSAyIHNldXJhdCBvYmplY3RzIHdpdGggc2V1cmF0IGludGVncmF0aW9uIChjY2EpCmBgYAoKYGBge3IsIENDQSwgZXZhbD0ocGFydDIgPT0gVFJVRSApLGluY2x1ZGU9RkFMU0V9CiMgR2VuZSBzZWxlY3Rpb24gZm9yIGlucHV0IHRvIENDQQpGaW5kVmFyaWFibGVGZWF0dXJlcyhvYmplY3QgPSBTZXVyYXQxLCAKICAgICAgICBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDAsIHZlcmJvc2UgPSBGQUxTRSkKRmluZFZhcmlhYmxlRmVhdHVyZXMob2JqZWN0ID0gU2V1cmF0MiwgCiAgICAgICAgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyMDAwLCB2ZXJib3NlID0gRkFMU0UpCgpleHAuYW5jaG9ycyA8LSBGaW5kSW50ZWdyYXRpb25BbmNob3JzKG9iamVjdC5saXN0ID0gYyhTZXVyYXQyLFNldXJhdDEpLCBkaW1zID0gMTozMCkKCmdlbmUxIDwtIHJvd25hbWVzKEdldEFzc2F5RGF0YShTZXVyYXQxLCBhc3NheSA9ICJSTkEiLCBzbG90ID0gImRhdGEiICkpCmdlbmUyIDwtIHJvd25hbWVzKEdldEFzc2F5RGF0YShTZXVyYXQyLCBhc3NheSA9ICJSTkEiLCBzbG90ID0gImRhdGEiICkpCmNvbW1vbl9nZW5lcyA8LSBSZWR1Y2UoaW50ZXJzZWN0LCBsaXN0KGdlbmUxLGdlbmUyKSkKCmV4cDEuMi5pbnRlZ3JhdGVkIDwtIEludGVncmF0ZURhdGEoYW5jaG9yc2V0ID0gZXhwLmFuY2hvcnMsIGZlYXR1cmVzLnRvLmludGVncmF0ZSA9IGNvbW1vbl9nZW5lcyxkaW1zID0gMTozMCkKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CmEgPC0gbGVuZ3RoKGdlbmUxKQpiIDwtIGxlbmd0aChnZW5lMikKYyA8LSBsZW5ndGgoY29tbW9uX2dlbmVzKQoKcHJpbnQocGFzdGUoIldlIGlkZW50aWZpZWQgIixhLCIgZXhwcmVzc2VkIGluIHNhbXBsZTEgYW5kICIsYiwiIGV4cHJlc3NlZCBpbiBzYW1wbGUyLiIsYywiYXJlIGluIGNvbW1vbiBpbiB0aGlzIHR3byBzZXQgYW5kIHdpbGwgdGhlIGludGVncmF0ZWQgaW4gdGhlIG1lcmdlZCBhbmQgY29ycmVjdGVkIG9iamVjdC4iKSwgcXVvdGUgPSBGQUxTRSkgCgpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIFVNQVA6CgojIEFuYWx5c2lzIHBhcnQKCiMjIFNhbXBsZSBJbmZvcm1hdGlvbgoKVGhlIGFuYWx5c2lzIHdpbGwgYmUgcnVuIG9uIHRoZSByZXBsaWNhdGUgMSBhbmQgMi4KCkR1cmluZyB0aGUgc2FtcGxlIGxvYWRpbmcsIHdlIGZpbHRlciBjZWxscyB0aGF0IGRvIG5vdCBwYXNzIHRoZSBmb2xsb3dpbmcgZmlsdGVycy4gV2UgYWxzbyBmaWx0ZXIgY2VsbHMgdGhhdCBhcmUgZGV0ZWN0ZWQgYXMgaHVtYW4vbW91c2UgbXVsdGlwbGV0IHVzaW5nIHRoZWlyIGJhcmNvZGVzLiAgCkhlcmUgYXJlIHRoZSBkZXNjcmlwdGlvbiBvZiB0aG9zZSBwYXJhbWV0ZXJzIGluIHRoZSBTZXVyYXQgKkNyZWF0ZVNldXJhdE9iamVjdCogZnVuY3Rpb246CgoqIG1pbi5nZW5lczogSW5jbHVkZSBjZWxscyB3aGVyZSBhdCBsZWFzdCB0aGlzIG1hbnkgZ2VuZXMgYXJlIGRldGVjdGVkCiogbWluLmNlbGxzOiBJbmNsdWRlIGdlbmVzIHdpdGggZGV0ZWN0ZWQgZXhwcmVzc2lvbiBpbiBhdCBsZWFzdCB0aGlzIG1hbnkgY2VsbHMKCmBgYAoKYGBge3IgZmlsdGVycywgZXZhbD0ocGFydDIgPT0gVFJVRSApLHJlc3VsdHM9J2FzaXMnLGluY2x1ZGU9RkFMU0V9CiMgQWZmaWNoZSBsZXMgcGFyYW1ldHJlcwpGaWx0ZXJfcGFyYW1ldGVycyA8LSBkYXRhLmZyYW1lKCkKRmlsdGVyX3BhcmFtZXRlcnNbIlZhbHVlIiwgIm1pbi5jZWxscyJdIDwtIDMKRmlsdGVyX3BhcmFtZXRlcnNbIlZhbHVlIiwgIm1pbi5nZW5lcyJdIDwtIDIwMAprYWJsZShGaWx0ZXJfcGFyYW1ldGVycywgImh0bWwiLCBhbGlnbiA9ICJjIikgJT4lIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIikpCmBgYAoKYGBge3IsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQphIDwtIGxlbmd0aChjb2xuYW1lcyhleHAxLjIuaW50ZWdyYXRlZCkpCgpwcmludChwYXN0ZSgiQWZ0ZXIgdGhvc2UgZmlsdGVycywgYW5kIG1lcmdpbmcgTVlDX1BURU5fMDEgYW5kIE1ZQ19QVEVOMDIgdGhlIHJlbWFpbmluZyBjZWxsIG51bWJlciBpcyIsYSksIHF1b3RlID0gRkFMU0UpIAoKYGBgCgoKYGBge3IgY2VsbF9zZWxlY3QsZXZhbD0ocGFydDIgPT0gVFJVRSApLCByZXN1bHRzPSdhc2lzJyxpbmNsdWRlPUZBTFNFfQojIyMgYWRkIEV4cDEgY2VsbCBpZGVudGl0eQojYWRkIEV4cDEgY2VsbCBpZGVudGl0eQpIVE9fY3I2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1jdHJsIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fY3Q2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1jdHJsIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fbXI2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1NIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fbXQ2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1NIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcHI2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1QIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcHQ2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1QIiApKSwiXzIiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcG1yNiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MUBtZXRhLmRhdGEsIE1VTFRJX0lEID09ICJTcGxlZW4tTVAiICkpLCJfMiIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCkhUT19wbXQ2IDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQxQG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1NUCIgKSksIl8yIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKCiMjIyBhZGQgRXhwMiBjZWxsIGlkZW50aXR5CkhUT19jcjIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICkpLCJfMSIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCkhUT19jdDIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtY3RybCIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX21yMiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlNwbGVlbi1NIiApKSwiXzEiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fbXQyIDwtIGludGVyc2VjdChwYXN0ZTAocm93Lm5hbWVzKHN1YnNldChTZXVyYXQyQG1ldGEuZGF0YSwgTVVMVElfSUQ9PSAiVGh5bXVzLU0iICkpLCJfMSIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCkhUT19wcjIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJTcGxlZW4tUCIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX3B0MiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlRoeW11cy1QIiApKSwiXzEiKSxjb2xuYW1lcyh4ID0gZXhwMS4yLmludGVncmF0ZWQpKQpIVE9fcG1yMiA8LSBpbnRlcnNlY3QocGFzdGUwKHJvdy5uYW1lcyhzdWJzZXQoU2V1cmF0MkBtZXRhLmRhdGEsIE1VTFRJX0lEPT0gIlNwbGVlbi1NUCIgKSksIl8xIiksY29sbmFtZXMoeCA9IGV4cDEuMi5pbnRlZ3JhdGVkKSkKSFRPX3BtdDIgPC0gaW50ZXJzZWN0KHBhc3RlMChyb3cubmFtZXMoc3Vic2V0KFNldXJhdDJAbWV0YS5kYXRhLCBNVUxUSV9JRD09ICJUaHltdXMtTVAiICkpLCJfMSIpLGNvbG5hbWVzKHggPSBleHAxLjIuaW50ZWdyYXRlZCkpCgoKCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YSRIVE8gPSAibm90aGluZyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19jcjIsXSRIVE8gPSAiV1Qgc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX2N0MixdJEhUTyA9ICJXVCB0aHltdXMiCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fY3I2LF0kSFRPID0gIldUIHNwbGVlbiIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19jdDYsXSRIVE8gPSAiV1QgdGh5bXVzIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3ByMixdJEhUTyA9ICJQVEVOLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fcHQyLF0kSFRPID0gIlBURU4tIHRoeW11cyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19wcjYsXSRIVE8gPSAiUFRFTi0gc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3B0NixdJEhUTyA9ICJQVEVOLSB0aHltdXMiCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fbXIyLF0kSFRPID0gIk1ZQy0gc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX210MixdJEhUTyA9ICJNWUMtIHRoeW11cyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19tcjYsXSRIVE8gPSAiTVlDLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fbXQ2LF0kSFRPID0gIk1ZQy0gdGh5bXVzIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3BtcjIsXSRIVE8gPSAiTXljLSBQVEVOLSBzcGxlZW4iCmV4cDEuMi5pbnRlZ3JhdGVkQG1ldGEuZGF0YVtIVE9fcG10MixdJEhUTyA9ICJNeWMtIFBURU4tIHRoeW11cyIKZXhwMS4yLmludGVncmF0ZWRAbWV0YS5kYXRhW0hUT19wbXI2LF0kSFRPID0gIk15Yy0gUFRFTi0gc3BsZWVuIgpleHAxLjIuaW50ZWdyYXRlZEBtZXRhLmRhdGFbSFRPX3BtdDYsXSRIVE8gPSAiTXljLSBQVEVOLSB0aHltdXMiCgpIVE9fdGh5bXVzID0gYyhIVE9fY3QyLEhUT19tdDIsSFRPX3B0MixIVE9fcG10MixIVE9fY3Q2LEhUT19tdDYsSFRPX3B0NixIVE9fcG10NikKSFRPX3NwbGVlbiA9IGMoSFRPX2NyMixIVE9fbXIyLEhUT19wcjIsSFRPX3BtcjIsSFRPX2NyNixIVE9fbXI2LEhUT19wcjYsSFRPX3BtcjYpCgppZGVudGlmaWVkIDwtIGMoSFRPX3RoeW11cyxIVE9fc3BsZWVuKQpWbG5QbG90KGV4cDEuMi5pbnRlZ3JhdGVkLGZlYXR1cmVzID0gIm5GZWF0dXJlX1JOQSIscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikKVmxuUGxvdChleHAxLjIuaW50ZWdyYXRlZCxmZWF0dXJlcyA9ICJuRmVhdHVyZV9STkEiLHB0LnNpemUgPSAwLjEsIGxvZyA9IFRSVUUsICBncm91cC5ieSA9ICJIVE8iKQpWbG5QbG90KGV4cDEuMi5pbnRlZ3JhdGVkLGZlYXR1cmVzID0gIm5GZWF0dXJlX1JOQSIscHQuc2l6ZSA9IDAuMSwgbG9nID0gVFJVRSwgIGdyb3VwLmJ5ID0gIm9yaWcuaWRlbnQiKQoKU2V1cmF0IDwtIGV4cDEuMi5pbnRlZ3JhdGVkCmBgYAoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBVTUFQIGFuZCBjbHVzdGVyaW5nIHBhcmFtZXRlcgpgYGAKCmBgYHtyIFNpZ25pZmljYW50X1BDX21lcmdlLCBldmFsPShwYXJ0MiA9PSBUUlVFICksaW5jbHVkZT1GQUxTRX0KIyBUcmFpdGVtZW50IGRlIGwnb2JqZXQKU2V1cmF0IDwtIFNjYWxlRGF0YSggb2JqZWN0ID0gIFNldXJhdCwgCiAgICAgICAgICAgICAgICAgICAgICBhc3NheT0iaW50ZWdyYXRlZCIsCiAgICAgICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAjZG8uc2NhbGUgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgIGRvLmNlbnRlciA9IFRSVUUpCiAgClNldXJhdCA8LSBSdW5QQ0Eob2JqZWN0ID0gU2V1cmF0LCBmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMoU2V1cmF0KSwgbnBjcyA9IDUwLCBzZWVkLnVzZSA9IDEyMzQsIHZlcmJvc2UgPSBGQUxTRSkKICAKRWxib3dQbG90KFNldXJhdCwgbmRpbXMgPSA0MCwgcmVkdWN0aW9uID0gInBjYSIpCiAgClNldXJhdCA8LSBQcm9qZWN0RGltKG9iamVjdCA9IFNldXJhdCwKICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICBuZmVhdHVyZXMucHJpbnQgPSAyMCwKICAgICAgICAgICAgICAgICAgZGltcy5wcmludCA9IDE6MTIpCiAgClNldXJhdCA8LSBGaW5kTmVpZ2hib3JzKG9iamVjdCA9IFNldXJhdCwgCiAgICAgICAgICAgICAgICAgIGRpbXMgPSAxOjEyICwgCiAgICAgICAgICAgICAgICAgIGFzc2F5PSJpbnRlZ3JhdGVkIiwKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFKSMsIAogICAgICAgICAgICAgICAgICAjZm9yY2UucmVjYWxjID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICNyZWR1Y3Rpb24gPSAicGNhIikKICAKU2V1cmF0IDwtIEZpbmRDbHVzdGVycyhvYmplY3QgPSBTZXVyYXQsIAogICAgICAgICAgICAgICAgICByZXNvbHV0aW9uID0gMSwKICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICB2ZXJib3NlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgIHJhbmRvbS5zZWVkID0gMTIzNCkKICAgIAogICNUbyBtYWtlIHRoZSBVTUFQCiAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKU2V1cmF0IDwtIFJ1blVNQVAob2JqZWN0ID0gU2V1cmF0LCByZWR1Y3Rpb24gPSAicGNhIiwgc2VlZC51c2UgPSAxMjM0LCBkaW1zID0gMToxMikKICAKRGltUGxvdChvYmplY3QgPSBTZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpCiAgCnNhdmUoU2V1cmF0LCBmaWxlID0gcGFzdGUwKE9VVFBVVF9QQVRILCAiU2V1cmF0LWludGVncmF0ZWRfcmVwMV9yZXAyLlJvYmoiKSkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBNZXJnZSBjaGVja2luZyB7LnRhYnNldH0KIyMjIEhUTwpgYGAKCmBgYHtyLGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1GQUxTRX0KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiSFRPIiwgZG8ubGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMSkrCiAgICAgICAgICAgZ2d0aXRsZSgiVU1BUCBjb2xvcnJlZCBieSBIVE8gY2xhc3NpZmljYXRpb24iKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIyBPcmlnLmlkZW50cwpgYGAKCmBgYHtyLCBldmFsPShwYXJ0MiA9PSBUUlVFICksZWNobz1GQUxTRX0KZ2dwbG90bHkoRGltUGxvdChTZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIGRvLmxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDEpKQpgYGAKCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIFQtY2VsbCBzZWxlY3Rpb24gey50YWJzZXR9CkFjY29yZGluZyB0byBULWNlbGwgbWFya2VycyB3ZSB3aWxsIGV4Y2x1ZGUgQ2QzZCBsb3cgY2x1c3RlcnM6IDEzIChCY2VsbHMpLCAxMSwgMTQsIDE3IChtb25vY3l0ZXMvbWFjcm9waGFnZXMpLgpBY2NvcmRpbmcgdG8gVC1jZWxsIG1hcmtlcnMgd2Ugd2lsbCBleGNsdWRlIENkM2QvQ2QzZSBsb3cgY2x1c3RlcnM6IDExIChCY2VsbHMpLCAxMywgMTcsIDE4LCAxOSAobW9ub2N5dGVzL21hY3JvcGhhZ2VzKSwgMTYsIDE0IChJTEMvTkspLgoKIyMjIEtub3duIFJOQSBCIGFuZCBUIG1hcmtlcnMKYGBgCgpgYGB7ciBidF9tYXJrZXJzX2NoZWNraW5nLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89RkFMU0V9CkRpbVBsb3QoU2V1cmF0LCBsYWJlbCA9IFQpCmJjZWxsX2tub3duX21hcmtlcnMgPC0gYygiQ2Q3NCIsIk1zNGExIiwiQ2QxOSIsIkNkM2QiKQpGZWF0dXJlUGxvdChvYmplY3QgPSBTZXVyYXQsIGZlYXR1cmVzID0gYmNlbGxfa25vd25fbWFya2VycywgcmVkdWN0aW9uID0gInVtYXAiLCAgY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpiY2VsbF9rbm93bl9tYXJrZXJzIDwtIGMoIkNkMTQiLCJGY2dyMyIsIlRyZGMiLCJDZDNkIikKRmVhdHVyZVBsb3Qob2JqZWN0ID0gU2V1cmF0LCBmZWF0dXJlcyA9IGJjZWxsX2tub3duX21hcmtlcnMsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgIGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKRmVhdHVyZVBsb3Qob2JqZWN0ID0gU2V1cmF0LCBmZWF0dXJlcyA9IGMoIklsMnJhIiwiS2xyZzEiLCJJbDdyIiwiUm9yYSIpLCByZWR1Y3Rpb24gPSAidW1hcCIsIG9yZGVyID0gVFJVRSwgY29scyA9IGMoImdyZXkiLCAibGlnaHQgYmx1ZSIsImN5YW4zIiwiY3lhbjQiLCJkb2RnZXJibHVlMyIsImJsdWUiLCJtZWRpdW1zbGF0ZWJsdWUiLCJwdXJwbGUiLCJvcmNoaWQzIiwicmVkIiwiYnJvd24iLCJibGFjayIpKQpGZWF0dXJlUGxvdChvYmplY3QgPSBTZXVyYXQsIGZlYXR1cmVzID0gYygiRW9tZXMiLCJOY3IxIiwiVGJ4MjEiLCJLaXQiKSwgcmVkdWN0aW9uID0gInVtYXAiLCBvcmRlciA9IFRSVUUsIGNvbHMgPSBjKCJncmV5IiwgImxpZ2h0IGJsdWUiLCJjeWFuMyIsImN5YW40IiwiZG9kZ2VyYmx1ZTMiLCJibHVlIiwibWVkaXVtc2xhdGVibHVlIiwicHVycGxlIiwib3JjaGlkMyIsInJlZCIsImJyb3duIiwiYmxhY2siKSkKI05yYzEgPSBOSwojSUw3UiB0byBzZXBhcmF0ZSBJTEMgZnJvbSBOSzsgSUw3UisgRU9NRVMrIHNob3VsZCBiZSBJTEMxOyBFT01FUysgSUw3Ui0gc2hvdWxkIGJlIE5LCmBgYAoKYGBge3IgVGNlbGxfc2VsZWN0aW9uLCBldmFsPShwYXJ0MiA9PSBUUlVFICksZWNobz1GQUxTRX0KI3JlbW92ZSBjbHVzdGVyIDExLDEyLDEzLDE3ICgjQmNlbGxzICYgbWFjcm9waGFnZXMpClQuU2V1cmF0IDwtIHN1YnNldCh4ID0gU2V1cmF0LCBpZGVudHMgPSBjKCIxMSIsIjEzIiwiMTQiLCIxNiIsIjE3IiwiMTgiLCIxOSIpLCBpbnZlcnQgPSBUUlVFKQpgYGAKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMgcmUgY2x1c3RlcmluZwpgYGAKCmBgYHtyLCBpbmNsdWRlPUZBTFNFLCBldmFsPShwYXJ0MiA9PSBUUlVFICl9CiMgSU5URUdSQVRFIE9CSkVDVCBBTkQgU0FWRQoKIyBTZWxlY3Rpb24gd2FzIGFscmVhZHkgZG9uZSBhdCB0aGUgaW50ZWdyYXRpb24gc3RlcCwgZXZlbiBhZnRlciByZXN1YnNldHRpbmcgaXQgaXMgd29ydGggdG8gcmVzZWxlY3QgKGh0dHBzOi8vZ2l0aHViLmNvbS9zYXRpamFsYWIvc2V1cmF0L2lzc3Vlcy8xNTI4KS4gUk5BIHNob3VsZCBiZSB1c2VkLCBidXQgdGhlbiBiYXRjaCBpcyBiYWNrLCBzdWJzZXR0aW5nIGJlZm9yZSBpbnRlZ3JhdGlvbiBpcyBub3QgZ29vZCBuZWl0aGVyIChiZXR0ZXIgdG8ga2VlcCBjZWxscyB0aGF0IGNhbiBiZSBhbGlnbmVkKS4uLiAKICAKVC5TZXVyYXQgPC0gU2NhbGVEYXRhKCBvYmplY3QgPSAgVC5TZXVyYXQsIAogICAgICAgICAgICAgICAgICAgICAgYXNzYXk9ImludGVncmF0ZWQiLAogICAgICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgI2RvLnNjYWxlID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBkby5jZW50ZXIgPSBUUlVFKQogIApULlNldXJhdCA8LSBSdW5QQ0Eob2JqZWN0ID0gVC5TZXVyYXQsIGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhULlNldXJhdCksIG5wY3MgPSAxMDAsIHNlZWQudXNlID0gMTIzNCwgdmVyYm9zZSA9IEZBTFNFKQogIApFbGJvd1Bsb3QoVC5TZXVyYXQsIG5kaW1zID0gNTAsIHJlZHVjdGlvbiA9ICJwY2EiKQoKVC5TZXVyYXQgPC0gUHJvamVjdERpbShvYmplY3QgPSBULlNldXJhdCwKICAgICAgICAgICAgICAgICAgbmZlYXR1cmVzLnByaW50ID0gMjAsCiAgICAgICAgICAgICAgICAgIGRpbXMucHJpbnQgPSAxOjEwKQogIApULlNldXJhdCA8LSBGaW5kTmVpZ2hib3JzKG9iamVjdCA9IFQuU2V1cmF0LAogICAgICAgICAgICAgICAgICBhc3NheSA9ICJpbnRlZ3JhdGVkIiwKICAgICAgICAgICAgICAgICAgZGltcyA9IDE6MTggLCAKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFKSMsIAogICAgICAgICAgICAgICAgICAjZm9yY2UucmVjYWxjID0gVFJVRSwgCiAgICAgICAgICAgICAgICAgICNyZWR1Y3Rpb24gPSAicGNhIikKICAKICBULlNldXJhdCA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gVC5TZXVyYXQsIAogICAgICAgICAgICAgICAgICBhc3NheSA9ICJpbnRlZ3JhdGVkIiwKICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbiA9IDEuOCwKICAgICAgICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICByYW5kb20uc2VlZCA9IDEyMzQpCiAgI1RvIG1ha2UgdGhlIFVNQVAKICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwogIFQuU2V1cmF0IDwtIFJ1blVNQVAob2JqZWN0ID0gVC5TZXVyYXQsIHJlZHVjdGlvbiA9ICJwY2EiLCBzZWVkLnVzZSA9IDEyMzQsIGRpbXMgPSAxOjE4KQogIAogIERpbVBsb3Qob2JqZWN0ID0gVC5TZXVyYXQsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpCiAgcDEgPC0gRGltUGxvdChvYmplY3QgPSBULlNldXJhdCwgcmVkdWN0aW9uID0gInVtYXAiLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikKICBwMiA8LSBEaW1QbG90KG9iamVjdCA9IFQuU2V1cmF0LCByZWR1Y3Rpb24gPSAicGNhIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIsIAogICAgICBsYWJlbCA9IFRSVUUsIHJlcGVsID0gVFJVRSkgKyBOb0xlZ2VuZCgpCiAgCiAgZ3JpZC5hcnJhbmdlKHAxLHAyLG5yb3cgPSAxLCBuY29sID0yLCBuZXdwYWdlPVRSVUUpCgogIHNhdmUoVC5TZXVyYXQsIGZpbGUgPSBwYXN0ZTAoT1VUUFVUX1BBVEgsICJULVNldXJhdC1tZXJnZWRfY2xlYW4tc3Vic2V0IiwgIi5Sb2JqIikpCmBgYAoKYGBge3IgLCBldmFsPShwYXJ0MiA9PSBUUlVFICksZWNobz1GQUxTRX0KIyMjIGFkZCBFeHAyIGNlbGwgaWRlbnRpdHkgCnNwbGVlbi5jZWxscyA8LSBjKHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLWN0cmwiICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLU0iICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiU3BsZWVuLU1QIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlNwbGVlbi1QIiApKSkKCnRoeW11cy5jZWxscyA8LSBjKHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLWN0cmwiICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLU0iICkpLHJvdy5uYW1lcyhzdWJzZXQoVC5TZXVyYXRAbWV0YS5kYXRhLCBNVUxUSV9JRCA9PSAiVGh5bXVzLU1QIiApKSxyb3cubmFtZXMoc3Vic2V0KFQuU2V1cmF0QG1ldGEuZGF0YSwgTVVMVElfSUQgPT0gIlRoeW11cy1QIiApKSkKClQuU2V1cmF0QG1ldGEuZGF0YSR0aXNzdWUgPSAibm90aGluZyIKVC5TZXVyYXRAbWV0YS5kYXRhW3NwbGVlbi5jZWxscyxdJHRpc3N1ZSA9ICJTcGxlZW4iClQuU2V1cmF0QG1ldGEuZGF0YVt0aHltdXMuY2VsbHMsXSR0aXNzdWUgPSAiVGh5bXVzIgoKRGltUGxvdChULlNldXJhdCkKYGBgCgoKYGBge2FzaXMsIGV2YWw9KHBhcnQyID09IFRSVUUgKSwgZWNobz1UUlVFfQojIyBULWNlbGwgdW1hcHMgey50YWJzZXR9CiMjIyBIVE8KYGBgCgpgYGB7ciwgZXZhbD0ocGFydDIgPT0gVFJVRSApLGVjaG89RkFMU0V9CmdncGxvdGx5KERpbVBsb3QoVC5TZXVyYXQsIGdyb3VwLmJ5ID0gIk1VTFRJX0lEIikpCmBgYAoKCmBgYHthc2lzLCBldmFsPShwYXJ0MiA9PSBUUlVFICksIGVjaG89VFJVRX0KIyMjIGNsdXN0ZXJpbmcKYGBgCgpgYGB7ciwgZXZhbD0ocGFydDIgPT0gVFJVRSApLGVjaG89RkFMU0V9CihEaW1QbG90KFQuU2V1cmF0LCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gImludGVncmF0ZWRfc25uX3Jlcy4xLjgiLCBsYWJlbCA9IFRSVUUsIHB0LnNpemUgPSAxKSkKYGBgCgpgYGB7YXNpcywgZXZhbD0ocGFydDIgPT0gVFJVRSApLCBlY2hvPVRSVUV9CiMjIEVORCBPRiBQUkVQUk9DRVNTSU5HCldlIG9idGFpbiB0aGUgZmluYWwgb2JqZWN0IHdpdGggY2x1c3RlcmluZyB0byBzdGFydCB0aGUgYW5hbHlzaXMKYGBgCgo8ZGV0YWlscz4KICA8c3VtbWFyeT4qKlNlc3Npb24gSW5mbyoqPC9zdW1tYXJ5PgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAKPC9kZXRhaWxzPgo=